package com.zcy.utils;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.JwtBuilder;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.security.Key;
import java.util.Date;
import java.util.Map;

/**
 * JWT工具类
 */
public class JwtUtil {
    
    // 默认过期时间 24小时
    private static final long DEFAULT_EXPIRATION = 1000 * 60 * 60 * 24;
    
    // 默认签名密钥
    private static final String DEFAULT_SECRET = "zcyStudySystemSecretKeyzcyStudySystem";
    
    /**
     * 生成JWT令牌
     *
     * @param claims    要存储在令牌中的声明
     * @return 生成的JWT令牌
     */
    public static String createJWT(Map<String, Object> claims) {
        return createJWT(claims, DEFAULT_EXPIRATION);
    }
    
    /**
     * 生成JWT令牌
     *
     * @param claims      要存储在令牌中的声明
     * @param expiration  过期时间（毫秒）
     * @return 生成的JWT令牌
     */
    public static String createJWT(Map<String, Object> claims, long expiration) {
        return createJWT(claims, DEFAULT_SECRET, expiration);
    }
    
    /**
     * 生成JWT令牌
     *
     * @param claims      要存储在令牌中的声明
     * @param secret      签名密钥
     * @param expiration  过期时间（毫秒）
     * @return 生成的JWT令牌
     */
    public static String createJWT(Map<String, Object> claims, String secret, long expiration) {
        // 当前时间
        Date now = new Date();
        // 过期时间
        Date expireDate = new Date(now.getTime() + expiration);
        
        // 创建JWT构建器
        JwtBuilder builder = Jwts.builder()
                .setClaims(claims)             // 设置声明
                .setIssuedAt(now)              // 设置签发时间
                .setExpiration(expireDate);    // 设置过期时间
        
        // 设置签名算法和密钥
        Key key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
        builder.signWith(key, SignatureAlgorithm.HS256);
        
        // 生成JWT令牌
        return builder.compact();
    }
    
    /**
     * 解析JWT令牌
     *
     * @param token JWT令牌
     * @return 解析出的声明
     */
    public static Claims parseJWT(String token) {
        return parseJWT(token, DEFAULT_SECRET);
    }
    
    /**
     * 解析JWT令牌
     *
     * @param token  JWT令牌
     * @param secret 签名密钥
     * @return 解析出的声明
     */
    public static Claims parseJWT(String token, String secret) {
        Key key = Keys.hmacShaKeyFor(secret.getBytes(StandardCharsets.UTF_8));
        return Jwts.parserBuilder()
                .setSigningKey(key)
                .build()
                .parseClaimsJws(token)
                .getBody();
    }
    
    /**
     * 验证JWT令牌是否有效
     *
     * @param token JWT令牌
     * @return true表示有效，false表示无效
     */
    public static boolean validateJWT(String token) {
        return validateJWT(token, DEFAULT_SECRET);
    }
    
    /**
     * 验证JWT令牌是否有效
     *
     * @param token  JWT令牌
     * @param secret 签名密钥
     * @return true表示有效，false表示无效
     */
    public static boolean validateJWT(String token, String secret) {
        try {
            parseJWT(token, secret);
            return true;
        } catch (Exception e) {
            return false;
        }
    }
    
    /**
     * 从JWT令牌中获取特定声明的值
     *
     * @param token JWT令牌
     * @param key   声明的键
     * @return 声明的值
     */
    public static Object getClaimFromJWT(String token, String key) {
        Claims claims = parseJWT(token);
        return claims.get(key);
    }
}